﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace EEG_NIRS_Record
{
    public partial class Configuration : Form
    {
        bool first_show;  // 判断是否第一次显示
        int ele_radius = 0; // 电极或光极的半径
        bool bsetting = false;  // 判断是否开始设置电极或光极
        int type = 0;   // 判断设置 eeg or source or detector
        public List<Point> list = new List<Point>();   // 所有点（130个）
        public List<Point> eeg_list = new List<Point>();   // 设置好的eeg点
        public List<Point> nirs_list = new List<Point>();   // 设置好的nirs通道的位置
        List<Point> source_list = new List<Point>();    // 设置好的source点
        List<Point> detector_list = new List<Point>();  // 设置好的detector点
        List<Point> ch_source_list = new List<Point>();  // 各通道对应的source点
        List<Point> ch_detector_list = new List<Point>();  // 各通道对应的detector点
        public List<int> index_ch_source_list = new List<int>();  // 各通道对应的source点的index
        public List<int> index_ch_detector_list = new List<int>();  // 各通道对应的detector点的index
        public List<string> label_eeg_list = new List<string>();   // 设置好的eeg点的label
        public List<string> label_nirs_list = new List<string>();   // 设置好的nirs通道的label
        List<string> label_source_list = new List<string>();   // 设置好的esource点的label
        List<string> label_detector_list = new List<string>();   // 设置好的detector点的label
        Graphics g_location, g_quality;
        Brush brush = null;
        Brush quality_brush = null;
        Pen quality_pen = null;
        Pen nirs_ch_pen = null;
        int nirs_ch_index = 0;

        string[] probe_name = {"Fpz","F9","AFF5h","AFF1","AFF2","AFF6h","F10","FTT9h","FTT7h","FCC5h","FCC3h","FCC1h","FCC2h","FCC4h","FCC6h","FTT8h","FTT10h","TPP9h","TPP7h"
                              ,"CPP5h","CPP3h","CPP1h","CPP2h","CPP4h","CPP6h","TTP8h","TPP10h","POO9h","POO3h","POO4h","POO10h","Iz","Fp1","Fp2","F7","F3","Fz","F4","F8","FC5"
                              ,"FC1","FC2","FC6","T7","C3","Cz","C4","T8","TP9","CP5","CP1","CP2","CP6","TP10","P7","P3","Pz","P4","P8","PO9","O1","Oz","O2","PO10","AF7","AF3"
                              ,"AF4","AF8","F5","F1","F2","F6","FT9","FT7","FC3","FC4","FT8","FT10","C5","C1","C2","C6","TP7","CP3","CPz","CP4","TP8","P5","P1","P2","P6","PO7"
                              ,"PO3","POz","PO4","PO8","AFp3h","AFp4h","FTT9h","FTT7h","FFC5h","FFC3h","FFC1h","FFC2h","FFC4h","FFC6h","FFT8h","FFT10h","TTP7h","CCP5h","CCP3h"
                              ,"CCP1h","CCP2h","CCP4h","CCP6h","TTP8h","TTP10h","P9","PPO9h","PPO5h","PPO1","PPO2","PPO6h","PPO10h","I1","OI1h","OI2h","I2","FCz","AFz"};

        int _ShowType; // -1: 什么都不显示  0：只显示EEG  1：只显示NIRS  2：同时显示EEG和NIRS
        public int ShowType
        {
            get { return _ShowType; }
            set { _ShowType = value; }
        }
        public Configuration()
        {
            InitializeComponent();
            _ShowType = -1;
            first_show = true;
            quality_brush = Brushes.Gray;
            quality_pen = new Pen(Color.Gray, 2);
        }
        //该点pCurrent到指定点pTarget的距离
        public double DistanceTo(Point pCurrent, Point pTarget)
        {
            return Math.Sqrt((pCurrent.X - pTarget.X) * (pCurrent.X - pTarget.X) + (pCurrent.Y - pTarget.Y) * (pCurrent.Y - pTarget.Y));
        }
        public double DistanceTo(int x, int y, Point pTarget)
        {
            return Math.Sqrt((x - pTarget.X) * (x - pTarget.X) + (y - pTarget.Y) * (y - pTarget.Y));
        }
        /// <summary>
        /// 计算点P(x,y)与X轴正方向的夹角
        /// </summary>
        /// <param name="x">横坐标</param>
        /// <param name="y">纵坐标</param>
        /// <returns>夹角弧度</returns>
        private double radPOX(Point p)
        {
            double x = p.X;
            double y = p.Y;
            //P在(0,0)的情况
            if (x == 0 && y == 0) return 0;

            //P在四个坐标轴上的情况：x正、x负、y正、y负
            if (y == 0 && x > 0) return 0;
            if (y == 0 && x < 0) return Math.PI;
            if (x == 0 && y > 0) return Math.PI / 2;
            if (x == 0 && y < 0) return Math.PI / 2 * 3;

            //点在第一、二、三、四象限时的情况
            if (x > 0 && y > 0) return Math.Atan(y / x);
            if (x < 0 && y > 0) return Math.PI - Math.Atan(y / -x);
            if (x < 0 && y < 0) return Math.PI + Math.Atan(-y / -x);
            if (x > 0 && y < 0) return Math.PI * 2 - Math.Atan(-y / x);

            return 0;
        }

        /// <summary>
        /// 返回点P围绕点A旋转弧度rad后的坐标
        /// </summary>
        /// <param name="P">待旋转点坐标</param>
        /// <param name="A">旋转中心坐标</param>
        /// <param name="rad">旋转弧度</param>
        /// <param name="isClockwise">true:顺时针/false:逆时针</param>
        /// <returns>旋转后坐标</returns>
        public Point RotatePoint(Point P, Point A,
            double rad, bool isClockwise = true)
        {
            //点Temp1
            Point Temp1 = new Point(P.X - A.X, P.Y - A.Y);
            //点Temp1到原点的长度
            double lenO2Temp1 = DistanceTo(Temp1, new Point(0, 0));
            //∠T1OX弧度
            double angT1OX = radPOX(Temp1);
            //∠T2OX弧度（T2为T1以O为圆心旋转弧度rad）
            double angT2OX = angT1OX - (isClockwise ? 1 : -1) * rad;
            //点Temp2
            Point Temp2 = new Point((int)(lenO2Temp1 * Math.Cos(angT2OX)), (int)(lenO2Temp1 * Math.Sin(angT2OX)));
            //点Q
            return new Point(Temp2.X + A.X, Temp2.Y + A.Y);
        }

        private void Configuration_Load(object sender, EventArgs e)
        {
            if (first_show == false)
            {
                return;
            }
            first_show = false;
            string coordinate_filename = "AllProbes.locs";
            if (!File.Exists(coordinate_filename))
            {
                MessageBox.Show("AllProbes.locs doesn't exist! Please check it !");
                Environment.Exit(0);
            }
            FileStream fs = new FileStream(coordinate_filename, FileMode.Open);
            StreamReader sr = new StreamReader(fs);
            string str = sr.ReadLine();
            string[] temp = null;
            int[] cor = null;
            char[] separator = new char[] { '\t' };
            while (str != null) // 坐标顺序 红->绿->黄->黑->REF->GND
            {
                temp = str.Split(separator);
                cor = Array.ConvertAll(temp, element => int.Parse(element));
                list.Add(new Point(cor[1], cor[2]));
                str = sr.ReadLine();
            }
            sr.Close();
            fs.Close();
            //////////// 画“采集位置”的头
            pb_location.BackColor = Color.FromArgb(100, Color.BurlyWood);
            Bitmap location_backgroundimage = new Bitmap(pb_location.Width, pb_location.Height);
            Graphics g = Graphics.FromImage(location_backgroundimage);
            //高质量低速度呈现 指定是否将平滑处理（消除锯齿）应用于直线、曲线和已填充区域的边缘。
            g.PixelOffsetMode = PixelOffsetMode.HighQuality;
            g.SmoothingMode = SmoothingMode.HighQuality;
            DrawBrain(g);
            g.Dispose();
            pb_location.BackgroundImage = location_backgroundimage;
            Bitmap location_image = new Bitmap(pb_location.Width, pb_location.Height);
            pb_location.Image = location_image;
            g_location = Graphics.FromImage(location_image);
            g_location.PixelOffsetMode = PixelOffsetMode.HighQuality;
            g_location.SmoothingMode = SmoothingMode.HighQuality;
            //////////// 画“信号质量”的头
            pb_signal_quality.BackColor = Color.FromArgb(100, Color.BurlyWood);
            Bitmap quality_backgroundimage = new Bitmap(pb_signal_quality.Width, pb_signal_quality.Height);
            Graphics gg = Graphics.FromImage(quality_backgroundimage);
            //高质量低速度呈现 指定是否将平滑处理（消除锯齿）应用于直线、曲线和已填充区域的边缘。
            gg.PixelOffsetMode = PixelOffsetMode.HighQuality;
            gg.SmoothingMode = SmoothingMode.HighQuality;
            Quality_DrawBrain(gg);
            gg.Dispose();
            pb_signal_quality.BackgroundImage = quality_backgroundimage;
            Bitmap quality_image = new Bitmap(pb_signal_quality.Width, pb_signal_quality.Height);
            pb_signal_quality.Image = quality_image;
            g_quality = Graphics.FromImage(quality_image);
            g_quality.PixelOffsetMode = PixelOffsetMode.HighQuality;
            g_quality.SmoothingMode = SmoothingMode.HighQuality;
            ////////////
            InitComboBox();

            tp_user_information.BackColor = Color.FromArgb(165, Color.BurlyWood);
            rb_source.Checked = true;
        }
        private void InitComboBox()
        {
            comboBox.Items.Clear();
            comboBox.Items.Add("Select a layout");
            comboBox.Items.Add("32 Channels EEG");
            comboBox.Items.Add("64 Channels EEG");
            comboBox.SelectedIndex = 0;

            cb_source.Items.Clear();
            for (int i = 0; i < 16; i++)
            {
                cb_source.Items.Add("S" + (i + 1).ToString());
            }
            cb_source.SelectedIndex = 0;

            cb_detector.Items.Clear();
            for (int i = 0; i < 16; i++)
            {
                cb_detector.Items.Add("D" + (i + 1).ToString());
            }
            cb_detector.SelectedIndex = 0;
        }
        private void DrawBrain(Graphics g)
        {
            Pen pen_brain = new Pen(Color.Black, 2);
            Pen pen_elec = new Pen(Color.Gray, 2);
            Point center = list[45];
            int radius = (int)(list[31].Y - list[45].Y);
            // draw brain borad
            g.DrawEllipse(pen_brain, getRectangle(center, radius));
            g.DrawEllipse(pen_brain, getRectangle(center, (int)(list[45].Y - list[0].Y)));
            // draw ears
            int ear_width = 20;
            int ear_height = 50;
            g.DrawEllipse(pen_brain, new Rectangle((int)center.X - radius - ear_width, (int)center.Y - ear_height, ear_width, 2 * ear_height));
            g.DrawEllipse(pen_brain, new Rectangle((int)center.X + radius, (int)center.Y - ear_height, ear_width, 2 * ear_height));
            // draw nose
            Point ln = RotatePoint(new Point(center.X, center.Y - radius), center, Math.PI / 22, false);
            Point rn = RotatePoint(new Point(center.X, center.Y - radius), center, Math.PI / 22);
            Point tip = new Point(center.X, center.Y - radius - 40);
            g.DrawLine(pen_brain, (int)tip.X, (int)tip.Y, (int)ln.X, (int)ln.Y);
            g.DrawLine(pen_brain, (int)tip.X, (int)tip.Y, (int)rn.X, (int)rn.Y);
            ////
            g.DrawLine(pen_brain, (int)center.X, (int)center.Y + radius, (int)center.X, (int)center.Y - radius);
            g.DrawLine(pen_brain, (int)center.X + radius, (int)center.Y, (int)center.X - radius, (int)center.Y);

            ele_radius = 13;
            //Font font = new Font("宋体", 7);
            for (int i = 0; i < list.Count; i++)
            {
                g.DrawEllipse(pen_elec, getRectangle((int)list[i].X, (int)list[i].Y, ele_radius));
                //g.DrawString(probe_name[i], font, Brushes.Black, (int)list[i].x - ele_radius + 2, (int)list[i].y - 3);
            }
        }
        private void Quality_DrawBrain(Graphics g)
        {
            Pen pen_brain = new Pen(Color.Black, 2);            
            Point center = list[45];
            int radius = (int)(list[31].Y - list[45].Y);
            // draw brain borad
            g.DrawEllipse(pen_brain, getRectangle(center, radius));
            // draw ears
            int ear_width = 20;
            int ear_height = 50;
            g.DrawEllipse(pen_brain, new Rectangle((int)center.X - radius - ear_width, (int)center.Y - ear_height, ear_width, 2 * ear_height));
            g.DrawEllipse(pen_brain, new Rectangle((int)center.X + radius, (int)center.Y - ear_height, ear_width, 2 * ear_height));
            // draw nose
            Point ln = RotatePoint(new Point(center.X, center.Y - radius), center, Math.PI / 22, false);
            Point rn = RotatePoint(new Point(center.X, center.Y - radius), center, Math.PI / 22);
            Point tip = new Point(center.X, center.Y - radius - 40);
            g.DrawLine(pen_brain, (int)tip.X, (int)tip.Y, (int)ln.X, (int)ln.Y);
            g.DrawLine(pen_brain, (int)tip.X, (int)tip.Y, (int)rn.X, (int)rn.Y);
            /////
            g.FillEllipse(Brushes.Green, new Rectangle(pb_signal_quality.Width - 130, pb_signal_quality.Height * 1 / 4 - 50, 100, 100));
            g.FillEllipse(Brushes.Yellow, new Rectangle(pb_signal_quality.Width - 130, pb_signal_quality.Height * 2 / 4 - 50, 100, 100));
            g.FillEllipse(Brushes.Red, new Rectangle(pb_signal_quality.Width - 130, pb_signal_quality.Height * 3 / 4 - 50, 100, 100));
        }
        public Rectangle getRectangle(int x_center, int y_center, int radius)
        {
            Rectangle rect = new Rectangle(x_center - radius, y_center - radius, 2 * radius, 2 * radius);
            return rect;
        }
        public Rectangle getRectangle(Point center, int radius)
        {
            Rectangle rect = new Rectangle((int)center.X - radius, (int)center.Y - radius, 2 * radius, 2 * radius);
            return rect;
        }
        private void rb_source_CheckedChanged(object sender, EventArgs e)
        {
            if (rb_source.Checked == true)
            {
                brush = new SolidBrush(Color.FromArgb(150, Color.Red));
                type = 0;
            }
        }

        private void rb_detector_CheckedChanged(object sender, EventArgs e)
        {
            if (rb_detector.Checked == true)
            {
                brush = new SolidBrush(Color.FromArgb(150, Color.Green));
                type = 1;
            }
        }

        private void rb_eeg_CheckedChanged(object sender, EventArgs e)
        {
            if (rb_eeg.Checked == true)
            {
                brush = new SolidBrush(Color.FromArgb(150, 0, 155, 255));
                type = 2;
            }
        }
        private void rb_nirs_ch_CheckedChanged(object sender, EventArgs e)
        {
            if (rb_nirs_ch.Checked == true)
            {
                nirs_ch_pen = new Pen(Color.FromArgb(150, Color.Yellow), 2);
                type = 3;
            }
        }

        private void bt_set_Click(object sender, EventArgs e)
        {
            if (bsetting == false)
            {
                bsetting = true;
                bt_clear.Enabled = true;
                comboBox.Enabled = false;
                bt_set.Text = "Stop";
            }
            else
            {
                bsetting = false;
                bt_clear.Enabled = false;
                if (cb_source.Items.Count == 16 && cb_detector.Items.Count == 16)
                {
                    comboBox.Enabled = true;
                }
                bt_set.Text = "Set";
            }
        }

        private void bt_clear_Click(object sender, EventArgs e)
        {
            switch (type)
            {
                case 0:
                    if (source_list.Count > 0)
                    {
                        cb_source.Items.Add(label_source_list[label_source_list.Count - 1]);

                        source_list.RemoveAt(source_list.Count - 1);
                        label_source_list.RemoveAt(label_source_list.Count - 1);
                    }
                    break;
                case 1:
                    if (detector_list.Count > 0)
                    {
                        cb_detector.Items.Add(label_detector_list[label_detector_list.Count - 1]);
                        detector_list.RemoveAt(detector_list.Count - 1);
                        label_detector_list.RemoveAt(label_detector_list.Count - 1);
                    }
                    break;
                case 2:
                    if (eeg_list.Count > 0)
                    {
                        eeg_list.RemoveAt(eeg_list.Count - 1);
                        label_eeg_list.RemoveAt(label_eeg_list.Count - 1);
                    }
                    if (eeg_list.Count == 0)
                    {
                        comboBox.SelectedIndex = 0;
                    }
                    break;
                case 3:
                    if (nirs_list.Count > 0)
                    {
                        nirs_list.RemoveAt(nirs_list.Count - 1);
                        ch_source_list.RemoveAt(ch_source_list.Count - 1);
                        ch_detector_list.RemoveAt(ch_detector_list.Count - 1);
                        index_ch_source_list.RemoveAt(index_ch_source_list.Count - 1);
                        index_ch_detector_list.RemoveAt(index_ch_detector_list.Count - 1);
                        label_nirs_list.RemoveAt(label_nirs_list.Count - 1);
                        nirs_ch_index-=2;
                    }
                    break;
            }
            UpdateProbe();
            if (source_list.Count == 0 && detector_list.Count == 0 && eeg_list.Count == 0)
            {
                bt_save.Enabled = false;
            }
        }

        private void bt_reset_Click(object sender, EventArgs e)
        {
            source_list.Clear();
            detector_list.Clear();
            nirs_list.Clear();
            eeg_list.Clear();
            ch_source_list.Clear();
            ch_detector_list.Clear();
            index_ch_source_list.Clear();
            index_ch_detector_list.Clear();
            label_eeg_list.Clear();
            label_nirs_list.Clear();
            label_source_list.Clear();
            label_detector_list.Clear();
            nirs_ch_index = 0;

            UpdateProbe();
            InitComboBox();
            bt_save.Enabled = false;
            comboBox.Enabled = true;
        }

        int layout_type = 0;
        private void comboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            // 是不是还得弄成只能设置一个 standard layout ? (避免不同的 standard layout 共用一个点) 
            // 如果设置 Customized 了，也不允许设置 standard layout，同样是避免共用一个点
            // 清除设置的 standard layout （source，detector，eeg 都要清除）
            source_list.Clear();
            label_source_list.Clear();
            detector_list.Clear();
            label_detector_list.Clear();
            eeg_list.Clear();
            label_eeg_list.Clear();

            switch (comboBox.SelectedIndex)
            {
                case 0:
                    break;
                case 1:
                    for (int i = 32; i < 64; i++)
                    {
                        eeg_list.Add(list[i]);
                        label_eeg_list.Add("E" + (i - 31).ToString());
                    }
                    bt_save.Enabled = true;
                    layout_type = 1;
                    break;
                case 2:
                    bt_save.Enabled = true;
                    layout_type = 2;
                    break;
            }
            UpdateProbe();
        }
        private void UpdateProbe()
        {
            g_location.Clear(Color.Transparent);
            Font font = new Font("宋体", 9, FontStyle.Bold);
            Brush red_brush = new SolidBrush(Color.FromArgb(150, Color.Red));
            Brush green_brush = new SolidBrush(Color.FromArgb(150, Color.Green));
            Brush blue_brush = new SolidBrush(Color.FromArgb(150, 0, 155, 255));
            for (int i = 0; i < source_list.Count; i++)
            {
                g_location.FillEllipse(red_brush, getRectangle(source_list[i], ele_radius));
                g_location.DrawString(label_source_list[i], font, Brushes.Black, (int)source_list[i].X + ele_radius, (int)source_list[i].Y - 5);
            }
            for (int i = 0; i < detector_list.Count; i++)
            {
                g_location.FillEllipse(green_brush, getRectangle(detector_list[i], ele_radius));
                g_location.DrawString(label_detector_list[i], font, Brushes.Black, (int)detector_list[i].X + ele_radius, (int)detector_list[i].Y - 5);
            }
            for (int i = 0; i < eeg_list.Count; i++)
            {
                g_location.FillEllipse(blue_brush, getRectangle(eeg_list[i], ele_radius));
                g_location.DrawString(label_eeg_list[i], font, Brushes.Black, (int)eeg_list[i].X + ele_radius, (int)eeg_list[i].Y - 5);
            }
            for (int i = 0; i < nirs_list.Count; i++)
            {
                g_location.DrawLine(nirs_ch_pen, ch_detector_list[i].X, ch_detector_list[i].Y, ch_source_list[i].X, ch_source_list[i].Y);
                g_location.DrawString(label_nirs_list[i], font, Brushes.Black, (int)nirs_list[i].X + 5, (int)nirs_list[i].Y - 5);
            }
            pb_location.Invalidate();
        }

        private void bt_save_Click(object sender, EventArgs e)
        {
            string filename = null;
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "locs文件(*.locs)|*.locs";
            if (sfd.ShowDialog() == DialogResult.OK)
            {
                filename = sfd.FileName;
            }
            FileStream fs = new FileStream(filename, FileMode.Create);
            StreamWriter sw = new StreamWriter(fs);
            for (int i = 0; i < source_list.Count; i++)
            {
                sw.WriteLine(label_source_list[i] + "\t" + (int)source_list[i].X + "\t" + (int)source_list[i].Y + "\t" + 0);
            }
            for (int i = 0; i < detector_list.Count; i++)
            {
                sw.WriteLine(label_detector_list[i] + "\t" + (int)detector_list[i].X + "\t" + (int)detector_list[i].Y + "\t" + 1);
            }
            for (int i = 0; i < ch_source_list.Count; i++)
            {
                sw.WriteLine("C" + (i + 1).ToString() + "\t" + (int)ch_source_list[i].X + "\t" + (int)ch_source_list[i].Y + "\t" + 3);
            }
            for (int i = 0; i < ch_detector_list.Count; i++)
            {
                sw.WriteLine("C" + (i + 1).ToString() + "\t" + (int)ch_detector_list[i].X + "\t" + (int)ch_detector_list[i].Y + "\t" + 4);
            }
            for (int i = 0; i < eeg_list.Count; i++)
            {
                sw.WriteLine(label_eeg_list[i] + "\t" + (int)eeg_list[i].X + "\t" + (int)eeg_list[i].Y + "\t" + 5);
            }
            sw.Close();
            fs.Close();
            MessageBox.Show("Save Complete!");
        }

        Point nirs = new Point();
        private void pb_location_Click(object sender, EventArgs e)
        {
            //MouseEventArgs Mouse_e = (MouseEventArgs)e;
            //if (Mouse_e.Button == MouseButtons.Left)
            //{
            //    MessageBox.Show("右键!");
            //}
            //if (Mouse_e.Button == MouseButtons.Right)
            //{
            //}
            if (bsetting == false)
            {
                return;
            }

            List<double> distance_list = new List<double>();
            Point current = new Point(((MouseEventArgs)e).X, ((MouseEventArgs)e).Y);
            for (int i = 0; i < list.Count; i++)
            {
                distance_list.Add(DistanceTo(current, list[i]));
            }
            var min_distance = distance_list.Min();
            if ((int)min_distance > ele_radius)
            {
                return;
            }
            int min_distance_index = distance_list.IndexOf(min_distance);
            Point selectedPoint = list[min_distance_index];

            string label = null;
            
            
            if (type == 3)
            {
                if (nirs_ch_index % 2 == 0)   // 设置nirs通道时，先选一个detector，再选一个source
                {
                    if (!source_list.Exists((Point p) => p.Equals(selectedPoint)))
                    {
                        MessageBox.Show("Please select a source !");
                    }
                    else
                    {
                        nirs_ch_index++;
                        ch_source_list.Add(selectedPoint);
                        //g_location.FillEllipse();
                        int source_index = source_list.IndexOf(selectedPoint);
                        Match m = Regex.Match(label_source_list[source_index], @"\d+");
                        int num = int.Parse(m.Value);
                        index_ch_source_list.Add(num - 1);
                        nirs.X = selectedPoint.X;
                        nirs.Y = selectedPoint.Y;                        
                    }
                    return;
                }
                else
                {
                    if (!detector_list.Exists((Point p) => p.Equals(selectedPoint))) // detector_list
                    {
                        MessageBox.Show("Please select a detector !");
                    }
                    else
                    {
                        nirs_ch_index++;
                        ch_detector_list.Add(selectedPoint);
                        int detector_index = detector_list.IndexOf(selectedPoint);
                        Match m = Regex.Match(label_detector_list[detector_index], @"\d+");
                        int num = int.Parse(m.Value);
                        index_ch_detector_list.Add(num - 1);
                        nirs.X = (nirs.X + selectedPoint.X) / 2;
                        nirs.Y = (nirs.Y + selectedPoint.Y) / 2;
                        nirs_list.Add(nirs);
                        label = "Ch" + nirs_ch_index / 2;
                        label_nirs_list.Add(label);
                        g_location.DrawLine(nirs_ch_pen, ch_detector_list[ch_detector_list.Count - 1].X, ch_detector_list[ch_detector_list.Count - 1].Y, ch_source_list[ch_source_list.Count - 1].X, ch_source_list[ch_source_list.Count - 1].Y);
                        Font fonts = new Font("宋体", 9, FontStyle.Bold);
                        g_location.DrawString(label, fonts, Brushes.Black, (int)nirs.X + 5, (int)nirs.Y - 5);
                        pb_location.Invalidate();                   
                    }
                    return;
                }
            }

            if (source_list.Exists((Point p) => p.Equals(selectedPoint)) || detector_list.Exists((Point p) => p.Equals(selectedPoint))
                || eeg_list.Exists((Point p) => p.Equals(selectedPoint)))
            {
                MessageBox.Show("This place has been setted !");
                return;
            }

            switch (type)
            {
                case 0:
                    source_list.Add(selectedPoint);
                    label = cb_source.Text;
                    label_source_list.Add(label);
                    cb_source.Items.Remove(label);
                    cb_source.SelectedIndex = 0;
                    break;
                case 1:
                    detector_list.Add(selectedPoint);
                    label = cb_detector.Text;
                    label_detector_list.Add(label);
                    cb_detector.Items.Remove(label);
                    cb_detector.SelectedIndex = 0;
                    break;
                case 2:
                    eeg_list.Add(selectedPoint);
                    label_eeg_list.Add(label);
                    break;
            }

            g_location.FillEllipse(brush, getRectangle(selectedPoint, ele_radius));
            Font font = new Font("宋体", 9, FontStyle.Bold);
            g_location.DrawString(label, font, Brushes.Black, (int)selectedPoint.X + ele_radius, (int)selectedPoint.Y - 5);
            pb_location.Invalidate();

            if (bt_save.Enabled == false)
            {
                bt_save.Enabled = true;
            }
        }

        private void rb_nirs_quality_CheckedChanged(object sender, EventArgs e)
        {
            g_quality.Clear(Color.Transparent);
            Font font = new Font("宋体", 9, FontStyle.Bold);
            for (int i = 0; i < source_list.Count; i++)
            {
                g_quality.FillEllipse(Brushes.Black, getRectangle(source_list[i], 5));
                g_quality.DrawString(label_source_list[i], font, Brushes.Black, (int)source_list[i].X + ele_radius, (int)source_list[i].Y - 5);
            }
            for (int i = 0; i < detector_list.Count; i++)
            {
                g_quality.FillEllipse(Brushes.Black, getRectangle(detector_list[i], 5));
                g_quality.DrawString(label_detector_list[i], font, Brushes.Black, (int)detector_list[i].X + ele_radius, (int)detector_list[i].Y - 5);
            }
            for (int i = 0; i < nirs_list.Count; i++)
            {
                //g_quality.FillEllipse(Brushes.Black, getRectangle(nirs_list[i], 5));
                g_quality.DrawLine(quality_pen, ch_detector_list[i].X, ch_detector_list[i].Y, ch_source_list[i].X, ch_source_list[i].Y);
                g_quality.DrawString(label_nirs_list[i], font, Brushes.Black, (int)nirs_list[i].X + 5, (int)nirs_list[i].Y - 5);
            }
            pb_signal_quality.Invalidate();
        }

        private void rb_eeg_quality_CheckedChanged(object sender, EventArgs e)
        {
            g_quality.Clear(Color.Transparent);
            Font font = new Font("宋体", 9, FontStyle.Bold);
            for (int i = 0; i < eeg_list.Count; i++)
            {
                g_quality.FillEllipse(quality_brush, getRectangle(eeg_list[i], ele_radius));
                g_quality.DrawString(label_eeg_list[i], font, Brushes.Black, (int)eeg_list[i].X + ele_radius, (int)eeg_list[i].Y - 5);
            }
            pb_signal_quality.Invalidate();
        }

        private void btn_complete_Click(object sender, EventArgs e)
        {
            if (tb_id.Text == "")
            {
                MessageBox.Show("Please add user ID !");
                return;
            }
            if (eeg_list.Count == 0 && detector_list.Count == 0 && source_list.Count == 0)
            {
                MessageBox.Show("Please add recording positions !");
                return;
            }
            if (eeg_list.Count > 0 && detector_list.Count > 0 && source_list.Count > 0)
            {
                _ShowType = 2;
            }
            else if (detector_list.Count > 0 && source_list.Count > 0)
            {
                _ShowType = 1;
            }
            else if (eeg_list.Count > 0)
            {
                _ShowType = 0;
            }

            this.DialogResult = DialogResult.OK;
            this.Close();
        }

    }
}
